# ============================================================================
# NFShmXFrame 主 CMakeLists.txt
# ============================================================================
# 使用模块化配置系统，提供清晰的代码组织和易于维护的结构
# ============================================================================

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)

# ============================================================================
# 加载 CMake 模块路径（必须在 include 之前）
# ============================================================================
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

# ============================================================================
# Clang 编译器配置（必须在 project() 之前）
# ============================================================================
# Linux 上默认使用 Clang，可以通过环境变量 USE_CLANG 控制
# Windows 上不考虑 Clang，使用 MSVC
# ============================================================================
if(UNIX AND NOT WIN32)
    include(ClangConfig)
endif()

project(ShmNFrame)

# ============================================================================
# 加载配置模块（按顺序）
# ============================================================================

# 1. 统一配置管理（项目根目录、版本、构建选项等）
include(Config)

# 2. 编译器配置（C++ 标准、编译器选项、警告设置等）
include(CompilerConfig)

# 3. 平台特定配置（Windows/Linux 包含目录、库路径等）
include(PlatformConfig)

# 4. 编译缓存加速配置（sccache/ccache）
include(CompileCache)

# 4.1. distcc 分布式编译配置（主机验证、JOBS 计算、动态均衡）
if(UNIX AND NOT WIN32)
    include(DistccConfig)
endif()

# 5. 构建类型配置（Release/Debug/DynamicRelease/DynamicDebug）
include(BuildTypeConfig)

# 6. 依赖管理配置（链接依赖关系优化）
include(Dependencies)

# 7. 编译性能优化模块（辅助函数）
include(CompileOptimization)

# 8. sccache 专用配置（如果使用 sccache）
if(WIN32 AND MSVC)
    include(SccacheConfig)
endif()

# ============================================================================
# 编译性能优化配置
# ============================================================================
# 检测是否使用分布式编译（distcc/icecc/yadcc）
# 分布式编译时，需要禁用某些优化以避免冲突
set(USING_DISTRIBUTED_COMPILE OFF)
if(DEFINED ENV{DISTCC_HOSTS} OR DEFINED ENV{ICECC_SCHEDULER_HOST} OR DEFINED ENV{YADCC_COORDINATOR_ADDR})
    set(USING_DISTRIBUTED_COMPILE ON)
    message(STATUS "检测到分布式编译环境，将调整优化策略")
    if(DEFINED ENV{DISTCC_HOSTS})
        message(STATUS "  模式: distcc")
    elseif(DEFINED ENV{ICECC_SCHEDULER_HOST})
        message(STATUS "  模式: icecc")
    elseif(DEFINED ENV{YADCC_COORDINATOR_ADDR})
        message(STATUS "  模式: yadcc")
    endif()
endif()

# 启用并行编译（如果支持且未使用分布式编译）
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.12" AND NOT USING_DISTRIBUTED_COMPILE)
    if(NOT DEFINED CMAKE_JOB_POOLS)
        include(ProcessorCount OPTIONAL)
        if(ProcessorCount_FOUND)
            ProcessorCount(N)
            if(NOT N EQUAL 0)
                set(CMAKE_JOB_POOL_COMPILE "compile_pool" CACHE STRING "Job pool for compilation")
                set(CMAKE_JOB_POOL_LINK "link_pool" CACHE STRING "Job pool for linking")
                math(EXPR COMPILE_JOBS "${N} * 2")
                set(JOB_POOL_COMPILE "compile_pool=${COMPILE_JOBS}" CACHE STRING "Compile job pool size")
                set(JOB_POOL_LINK "link_pool=${N}" CACHE STRING "Link job pool size")
            endif()
        endif()
    endif()
elseif(USING_DISTRIBUTED_COMPILE)
    message(STATUS "  跳过任务池设置（由分布式编译系统控制并行度）")
endif()

# 优化 CMake 配置阶段性能
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
    cmake_policy(SET CMP0071 NEW)
    cmake_policy(SET CMP0074 NEW)
endif()

# 优化依赖跟踪
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.20")
    set(CMAKE_DEPENDS_IN_PROJECT_ONLY ON CACHE BOOL "Only track dependencies within project")
endif()

# 优化文件系统操作
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")
    set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON CACHE BOOL "Skip install all dependency")
endif()

message(STATUS "========================================")
message(STATUS "✅ 编译性能优化已启用")
message(STATUS "========================================")
if(USING_DISTRIBUTED_COMPILE)
    message(STATUS "   ⚠️  分布式编译模式：部分优化已调整")
    message(STATUS "      - 任务池：由分布式编译系统控制")
    message(STATUS "      - LTO：已禁用（不兼容）")
else()
    if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.12")
        message(STATUS "   ✅ 并行编译优化")
    endif()
endif()
message(STATUS "   ✅ CMake 配置优化")
message(STATUS "   ✅ 依赖跟踪优化")
message(STATUS "========================================")

# ============================================================================
# 输出系统信息（调试用）
# ============================================================================
message(STATUS "========================================")
message(STATUS "系统信息")
message(STATUS "========================================")
message(STATUS "CMake 版本: ${CMAKE_VERSION}")
message(STATUS "主机系统: ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM}")
message(STATUS "目标系统: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM}")
message(STATUS "C 编译器: ${CMAKE_C_COMPILER}")
message(STATUS "C++ 编译器: ${CMAKE_CXX_COMPILER}")
message(STATUS "========================================")

# ============================================================================
# 输出编译标志（调试用）
# ============================================================================
message(STATUS "C 编译标志: ${CMAKE_C_FLAGS}")
message(STATUS "C++ 编译标志: ${CMAKE_CXX_FLAGS}")

# ============================================================================
# 添加子目录（根据构建类型和选项）
# ============================================================================
if(CMAKE_BUILD_TOOLS)
    # 只构建工具项目
    ADD_SUBDIRECTORY("src/NFTools")
else()
    # 构建主项目
    if(CMAKE_BUILD_TYPE STREQUAL "Release")
        ADD_SUBDIRECTORY("thirdparty")
        ADD_SUBDIRECTORY("src")
        ADD_SUBDIRECTORY("src/NFrame/NFPluginLoader")
        ADD_SUBDIRECTORY("src/NFrame/NFrameStatic")
        ADD_SUBDIRECTORY("src/NFServer/NFServerStatic")
        if(CMAKE_BUILD_GAME AND NOT CMAKE_BUILD_GAME STREQUAL "")
            message(STATUS "编译游戏项目: ${CMAKE_BUILD_GAME}")
            ADD_SUBDIRECTORY("game")
        else()
            message(STATUS "跳过游戏编译 (CMAKE_BUILD_GAME未设置或为空)")
        endif()
    elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
        ADD_SUBDIRECTORY("thirdparty")
        ADD_SUBDIRECTORY("src")
        ADD_SUBDIRECTORY("src/NFrame/NFPluginLoader")
        ADD_SUBDIRECTORY("src/NFrame/NFrameStatic")
        ADD_SUBDIRECTORY("src/NFServer/NFServerStatic")
        ADD_SUBDIRECTORY("src/NFTest/main")
        if(CMAKE_BUILD_GAME AND NOT CMAKE_BUILD_GAME STREQUAL "")
            message(STATUS "编译游戏项目: ${CMAKE_BUILD_GAME}")
            ADD_SUBDIRECTORY("game")
        else()
            message(STATUS "跳过游戏编译 (CMAKE_BUILD_GAME未设置或为空)")
        endif()
    elseif(CMAKE_BUILD_TYPE STREQUAL "DynamicRelease")
        ADD_SUBDIRECTORY("thirdparty")
        ADD_SUBDIRECTORY("src")
        ADD_SUBDIRECTORY("src/NFrame/NFPluginLoader")
        if(CMAKE_BUILD_GAME AND NOT CMAKE_BUILD_GAME STREQUAL "")
            message(STATUS "编译游戏项目: ${CMAKE_BUILD_GAME}")
            ADD_SUBDIRECTORY("game")
        else()
            message(STATUS "跳过游戏编译 (CMAKE_BUILD_GAME未设置或为空)")
        endif()
    elseif(CMAKE_BUILD_TYPE STREQUAL "DynamicDebug")
        ADD_SUBDIRECTORY("thirdparty")
        ADD_SUBDIRECTORY("src")
        ADD_SUBDIRECTORY("src/NFrame/NFPluginLoader")
        if(CMAKE_BUILD_GAME AND NOT CMAKE_BUILD_GAME STREQUAL "")
            message(STATUS "编译游戏项目: ${CMAKE_BUILD_GAME}")
            ADD_SUBDIRECTORY("game")
        else()
            message(STATUS "跳过游戏编译 (CMAKE_BUILD_GAME未设置或为空)")
        endif()
    endif()
endif()

# ============================================================================
# Install 配置
# ============================================================================
# 安装 NFServerController 到根目录
if(WIN32)
    if(EXISTS "${CMAKE_NFSHM_SOURCE_DIR}/tools/NFServerController.exe")
        install(PROGRAMS "${CMAKE_NFSHM_SOURCE_DIR}/tools/NFServerController.exe"
                DESTINATION ".")
        message(STATUS "将安装 NFServerController.exe 到根目录")
    endif()
else()
    if(EXISTS "${CMAKE_NFSHM_SOURCE_DIR}/tools/NFServerController")
        install(PROGRAMS "${CMAKE_NFSHM_SOURCE_DIR}/tools/NFServerController"
                DESTINATION ".")
        message(STATUS "将安装 NFServerController 到根目录")
    endif()
endif()

# 安装配置文件和游戏资源
if(INSTALL_GAME_DIR AND NOT INSTALL_GAME_DIR STREQUAL "")
    message(STATUS "将安装游戏资源 [${INSTALL_GAME_DIR}]:")

    # 创建日志目录
    install(CODE "
        file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/Bin/logs/${INSTALL_GAME_DIR}\")
        message(STATUS \"创建日志目录: Bin/logs/${INSTALL_GAME_DIR}\")
    ")
else()
    message(WARNING "未设置 GAME_DIR 或 CMAKE_BUILD_GAME，将跳过游戏资源安装")
    message(WARNING "  使用方法: cmake -DCMAKE_BUILD_GAME=LieRen ... 或设置环境变量 GAME_DIR=LieRen")
endif()

message(STATUS "二进制文件将安装到: ${BIN_INSTALL_DIR}")
message(STATUS "使用 'make install' 或 'cmake --build . --target install' 来执行安装")

